﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using BLL.Enum;
using BLL.Installer;
using BLL.Interface.Apply;
using BLL.Model.Apply;
using System.Data;
using BLL.DbAccess;
using BLL.Utility;
using Castle.Core.Logging;

namespace BLL.Implement.Apply
{
    public class ApplyInfoImpl : IApplyInfo
    {
        public ILogger Logger { get; set; }
        private readonly DefaultContext _defaultContext;
        private readonly DbSet<ApplyInfo> _applyInfoContext;

        public ApplyInfoImpl()
        {
            _defaultContext = ContainerHelper.Instance.Container.Resolve<DefaultContext>();
            _applyInfoContext = _defaultContext.ApplyInfoContext;
        }

        public bool AddApplyInfo(ApplyInfo applyInfo)
        {
            if (applyInfo.CurrentStatus == ApplyProcessStatus.Wait)
            {
                CreateDefaultApplyProcessInfo(applyInfo);
            }
            _applyInfoContext.Add(applyInfo);
            _defaultContext.SaveChanges();
            Logger.InfoFormat("新增了一条记录：{0}", applyInfo);
            return true;
        }

        private static void CreateDefaultApplyProcessInfo(ApplyInfo applyInfo)
        {
            applyInfo.Process = new List<ApplyProcess>
                                    {
                                        new ApplyProcess
                                            {
                                                ApprovalUserId = applyInfo.ApplyUserId,
                                                Status = ApplyProcessStatus.Wait,
                                                ApprovalComment = "接受申请"
                                            }
                                    };
        }

        public bool UpdateApplyInfo(ApplyInfo applyInfo)
        {
            _defaultContext.Entry(applyInfo).State = EntityState.Modified;
            if (applyInfo.CurrentStatus == ApplyProcessStatus.Wait)
            {
                CreateDefaultApplyProcessInfo(applyInfo);
            }       
            _defaultContext.SaveChanges();
            Logger.InfoFormat("更新了一条记录：{0}", applyInfo);
            return true;
        }

        public bool DeleteApplyInfoById(int id)
        {
            var applyInfo = FindApplyInfoById(id, true);
            if (applyInfo == null)
            {
                Logger.FatalFormat("删除失败：没有找到编号为{0}的记录", id);
                return false;
            }
            _applyInfoContext.Remove(applyInfo);
            _defaultContext.SaveChanges();
            Logger.InfoFormat("删除了一条记录：{0}", applyInfo);
            return true;
        }

        public bool DeleteAllApplyInfo()
        {
            const string sql = "delete from ApplyInfo";
            try
            {
                _defaultContext.Database.ExecuteSqlCommand(sql);
                return true;
            }
            catch (Exception e)
            {
                Logger.FatalFormat(string.Format("删除所有记录失败，SQL：{0};消息:{1}", sql, e.Message));
                return false;
            }
        }

        public IList<ApplyInfo> GetAllApplyInfo()
        {
            return _applyInfoContext.AsNoTracking().ToList();
        }

        public ApplyInfo FindApplyInfoById(int id, bool tracking)
        {
            return tracking
                       ? _applyInfoContext.Find(id)
                       : _applyInfoContext.AsNoTracking().FirstOrDefault(p => p.Id == id);
        }

        public IList<ApplyInfo> GetApplyInfoByFilter(dynamic condition, Tuple<string, string> sort, PageInfo page)
        {
            var query = _applyInfoContext.AsNoTracking().AsQueryable();

            sort = HandleSort(sort);

            query = HandleCondition(condition, query);

            if (page != null)
            {
                page.TotalRecords = query.Count();
                return query.OrderBy(sort.Item1, sort.Item2)
                                            .Skip(page.PageSize * (page.CurrentPage - 1))
                                            .Take(page.PageSize).ToList();
            }
            return query.ToList();
        }

        private static Tuple<string, string> HandleSort(Tuple<string, string> sort)
        {
            if (sort == null || string.IsNullOrWhiteSpace(sort.Item1) || string.IsNullOrWhiteSpace(sort.Item2))
            {
                sort = new Tuple<string, string>("Id", "asc");
            }
            else if (sort.Item1.ToLower() == "status")
            {
                sort = new Tuple<string, string>("CurrentStatusValue", sort.Item2);
            }
            return sort;
        }

        private static IQueryable<ApplyInfo> HandleCondition(dynamic condition, IQueryable<ApplyInfo> query)
        {
            if (!string.IsNullOrWhiteSpace(condition.Title))
            {
                string title = condition.Title;
                query = query.Where(p => p.Title.Contains(title));
            }

            if (!string.IsNullOrWhiteSpace(condition.ApplyUserName))
            {
                string userName = condition.ApplyUserName;
                query = query.Where(p => p.ApplyUser.UserName.Contains(userName));
            }

            if (!string.IsNullOrWhiteSpace(condition.ApplyUserAccount))
            {
                string account = condition.ApplyUserAccount;
                query = query.Where(p => p.ApplyUser.AccountName == account);
            }

            return query;
        }

        public bool ApprovalApply(int id, string approvalComment, int approvalUserId, ApplyProcessStatus status)
        {
            var applyInfo = FindApplyInfoById(id, true);
            try
            {
                if (applyInfo.CurrentStatus != ApplyProcessStatus.Wait)
                {
                    throw new Exception(string.Format("该申请的状态不是待审批；{0}", applyInfo));
                }
                applyInfo.Process = new List<ApplyProcess>
                                    {
                                        new ApplyProcess
                                        {
                                            ApprovalComment = approvalComment,
                                            ApprovalDate = DateTime.Now,
                                            ApprovalUserId = approvalUserId,
                                            Status = status
                                        }
                                    };
                applyInfo.CurrentStatus = status;
                _defaultContext.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                Logger.ErrorFormat(string.Format("执行审批出现错误：{0},消息{1}", applyInfo, e.Message));
                return false;
            }
        }

        public bool AddApplyInfo(IList<ApplyInfo> applyInfoList)
        {
            try
            {
                foreach (var entry in applyInfoList)
                {
                    _applyInfoContext.Add(entry);
                }
                int count = _defaultContext.SaveChanges();
                Logger.InfoFormat("{0}条记录被插入。", count);
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return false;
            }
        }

        public bool DeleteApplyInfoById(IList<int> applyInfoList)
        {
            try
            {
                foreach (var id in applyInfoList)
                {
                    var entryToDelete = FindApplyInfoById(id, true);
                    _applyInfoContext.Remove(entryToDelete);
                }
                int count = _defaultContext.SaveChanges();
                Logger.InfoFormat("{0}条记录被删除。", count);
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return false;
            }
        }

    }

}
